﻿using HelixToolkit.Wpf.SharpDX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace EditPlugin
{
    enum TextureMode
    {
        TextureMode_Raw,
        TextureMode_ETC1S,
        TextureMode_UASTC,
    };
    enum TextureKind
    {
        TextureKind_Generic,
        TextureKind_Color,
        TextureKind_Normal,
        TextureKind_Attrib,

        TextureKind__Count
    };

    [StructLayout(LayoutKind.Sequential)]
    internal struct GltfOptimizerSettings
    {
        public int pos_bits;
        public int tex_bits;
        public int nrm_bits;
        public int col_bits;
        [MarshalAs(UnmanagedType.I1)]
        public bool pos_normalized;
        [MarshalAs(UnmanagedType.I1)]
        public bool pos_float;
        public int trn_bits;
        public int rot_bits;
        public int scl_bits;
        public int anim_freq;
        [MarshalAs(UnmanagedType.I1)]
        public bool anim_const;
        [MarshalAs(UnmanagedType.I1)]
        public bool keep_nodes;
        [MarshalAs(UnmanagedType.I1)]
        public bool keep_materials;
        [MarshalAs(UnmanagedType.I1)]
        public bool keep_extras;
        [MarshalAs(UnmanagedType.I1)]
        public bool mesh_merge;
        [MarshalAs(UnmanagedType.I1)]
        public bool mesh_instancing;
        public float simplify_threshold;
        [MarshalAs(UnmanagedType.I1)]
        public bool simplify_aggressive;
        [MarshalAs(UnmanagedType.I1)]
        public bool simplify_lock_borders;
        public float simplify_debug;
        public int meshlet_debug;
        [MarshalAs(UnmanagedType.I1)]
        public bool texture_ktx2;
        [MarshalAs(UnmanagedType.I1)]
        public bool texture_embed;
        [MarshalAs(UnmanagedType.I1)]
        public bool texture_pow2;
        [MarshalAs(UnmanagedType.I1)]
        public bool texture_flipy;
        public float texture_scale;
        public int texture_limit;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public TextureMode[] texture_mode;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public int[] texture_quality;
        public int texture_jobs;
        [MarshalAs(UnmanagedType.I1)]
        public bool quantize;
        [MarshalAs(UnmanagedType.I1)]
        public bool compress;
        [MarshalAs(UnmanagedType.I1)]
        public bool compressmore;
        [MarshalAs(UnmanagedType.I1)]
        public bool fallback;
        public int verbose;
    }
    internal static class GltfOptimizerApi
    {
        const string DllName = "gltfoptimizer.dll";
        [DllImport(DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "gltfopt_getVersion")]
        public extern static string Version();
        [DllImport(DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, EntryPoint = "gltfopt_process")]
        public extern static int Process(string input, string output, string report, GltfOptimizerSettings settings);
        public static void Default(ref GltfOptimizerSettings settings)
        {
            settings.quantize = true;
            settings.pos_bits = 14;
            settings.tex_bits = 12;
            settings.nrm_bits = 8;
            settings.col_bits = 8;
            settings.trn_bits = 16;
            settings.rot_bits = 12;
            settings.scl_bits = 16;
            settings.anim_freq = 30;
            settings.simplify_threshold = 1.0f;
            settings.texture_scale = 1.0f;
            settings.texture_quality = new int[4];
            settings.texture_mode = new TextureMode[4];
            for (int kind = 0; kind < 4; ++kind)
                settings.texture_quality[kind] = 8;

            settings.compress = true;
            settings.compressmore = true;
            settings.keep_nodes = true;
        }
    }
}
